using System;
using System.Collections.Generic;
using System.Text;

namespace SilverlightBlowfish
{
    public class luozhuangBlowfish
    {
        private BlowfishCBC m_bfish;

        public luozhuangBlowfish(String key)
        {
            UnicodeEncoding encoding = new UnicodeEncoding();
            m_bfish = new BlowfishCBC(encoding.GetBytes(key), 0L);
        }

        ~luozhuangBlowfish()
        {
            m_bfish.CleanUp();
        }

        public String EncryptString(String sPlainText)
        {
            long lCBCIV;
            Random rm = new Random();
            int hi = rm.Next();
            int lo = rm.Next();
            lCBCIV = PublicFuntion.MakeLong(lo, hi);
            return EncStr(sPlainText, lCBCIV);
        }
        private String EncStr(String sPlainText, long lNewCBCIV)
        {
            int nStrLen = sPlainText.Length;
            byte[] buf = new byte[(nStrLen << 1 & -8) + 8];
            int nPos = 0;
            for (int nI = 0; nI < nStrLen; nI++)
            {
                char cActChar = sPlainText[nI];
                buf[nPos++] = (byte)(cActChar >> 8 & 0xff);
                buf[nPos++] = (byte)(cActChar & 0xff);
            }

            byte bPadVal = (byte)(buf.Length - (nStrLen << 1));
            while (nPos < buf.Length)
            {
                buf[nPos++] = bPadVal;
            }
            m_bfish.SetCBCIV(lNewCBCIV);
            m_bfish.Encrypt(buf);
            byte[] newCBCIV = new byte[8];
            PublicFuntion.LongToByteArray(lNewCBCIV, newCBCIV, 0);
            return PublicFuntion.BytesToBinHex(newCBCIV, 0, 8) + PublicFuntion.BytesToBinHex(buf, 0, buf.Length);
        }

        public String DecryptString(String sCipherText)
        {
            int nLen = sCipherText.Length >> 1 & -8;
            if (nLen < 8)
            {
                return null;
            }
            byte[] cbciv = new byte[8];
            int nNumOfBytes = PublicFuntion.BinHexToBytes(sCipherText, cbciv, 0, 0, 8);
            if (nNumOfBytes < 8)
            {
                return null;
            }
            m_bfish.SetCBCIV(cbciv);
            if ((nLen -= 8) == 0)
            {
                return "";
            }
            byte[] buf = new byte[nLen];
            nNumOfBytes = PublicFuntion.BinHexToBytes(sCipherText, buf, 16, 0, nLen);
            if (nNumOfBytes < nLen)
            {
                return null;
            }
            m_bfish.Decrypt(buf);
            int nPadByte = buf[buf.Length - 1] & 0xff;
            if (nPadByte > 8 || nPadByte < 0)
            {
                nPadByte = 0;
            }
            nNumOfBytes -= nPadByte;
            if (nNumOfBytes < 0)
            {
                return "";
            }
            else
            {
                return PublicFuntion.ByteArrayToUNCString(buf, 0, nNumOfBytes);
            }
        }
    }
}
